<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Canvas 9x7网格（基础版）</title>
    <style>
        body {
            font-family: Arial, sans-serif; /* 默认字体 */
            margin: 0; /* 外边距。去除默认 */
            padding: 20px;/* 内边距 */
            display: flex;/* 使用 Flexbox 布局 */
            flex-direction: column;/* 垂直方向 */
            align-items: center;/* 水平居中 */
            background-color: #f0f0f0;/* 背景色 */
        }
        h1 {
            color: #333;/* 标题颜色 */
        }
        canvas {
            border: 2px solid black; /* 2 像素宽的黑色实线边框 */
            background-color: white; /* 背景色设为白色 */
            box-shadow: 0 4px 8px rgba(0,0,0,0.1); /* 阴影效果。1）水平偏移量；2）垂直偏移量；3）模糊半径；4）阴影颜色 */
            margin: 10px 0; /* 外边距。上下各 10 像素 */
        }
        button {
            padding: 10px 15px;
            background-color: #4CAF50;
            color: white;
            border: none;
            border-radius: 4px;
            cursor: pointer;
            margin: 5px;
        }
        button:hover {
            background-color: #45a049;
        }
        .info {
            margin-top: 10px;/* 上外边距 */
            font-size: 16px;/* 字体大小 */
            color: #555;
        }
    </style>
</head>
<body>
    <h1>Canvas 9行7列网格</h1>
    
    <canvas id="gridCanvas" width="500" height="500"></canvas>
    
    <div>
        <button id="resetBtn">重置网格</button>
        <button id="resizeBtn">自适应大小</button>
    </div>
    
    <div class="info">
        当前单元格: <span id="cellInfo">未选择</span>
    </div>

    <script>
        document.addEventListener('DOMContentLoaded', () => {
            // 获取Canvas元素和2D上下文
            const canvas = document.getElementById('gridCanvas');
            const ctx = canvas.getContext('2d');
            
            // 网格配置
            const config = {
                rows: 9,            // 行数
                cols: 7,            // 列数
                lineWidth: 2,       // 线条宽度
                lineColor: '#000',  // 线条颜色
                fillColor: '#fff',  // 单元格填充色
                hoverColor: '#f0f0f0', // 悬停时的颜色
                selectedColor: '#531cb8', // 选中时的颜色
                showNumbers: true   // 是否显示单元格编号
            };
            
            // 存储单元格数据的数组
            let cells = [];
            let hoveredCell = null; // 当前鼠标悬停的单元格
            let selectedCell = null; // 当前选中的单元格
            
            // 初始化网格
            function initGrid(width, height) {
                cells = [];
                
                // 计算每个单元格的宽度和高度
                const cellWidth = width / config.cols;
                const cellHeight = height / config.rows;
                
                // 创建单元格数据
                for (let row = 0; row < config.rows; row++) {
                    for (let col = 0; col < config.cols; col++) {
                        cells.push({
                            row: row,
                            col: col,
                            x: col * cellWidth,
                            y: row * cellHeight,
                            width: cellWidth,
                            height: cellHeight,
                            isHovered: false,// 是否悬停
                            isSelected: false// 是否选中
                        });
                    }
                }
            }
            
            // 绘制网格
            function drawGrid() {
                // 清除Canvas
                ctx.clearRect(0, 0, canvas.width, canvas.height);
                
                // 绘制每个单元格
                cells.forEach(cell => {
                    // 设置填充颜色（根据是否悬停或选中）
                    ctx.fillStyle = cell.isSelected ? config.selectedColor : 
                                    cell.isHovered ? config.hoverColor : 
                                    config.fillColor;
                    
                    // 填充单元格背景
                    ctx.fillRect(cell.x, cell.y, cell.width, cell.height);
                    
                    // 设置线条样式
                    ctx.strokeStyle = config.lineColor;
                    ctx.lineWidth = config.lineWidth;
                    
                    // 绘制单元格边框
                    ctx.strokeRect(cell.x, cell.y, cell.width, cell.height);
                    
                    // 如果启用，绘制单元格编号
                    if (config.showNumbers) {
                        ctx.fillStyle = '#333';
                        ctx.font = '14px Arial';
                        ctx.textAlign = 'center';
                        ctx.textBaseline = 'middle';
                        ctx.fillText(`${cell.row + 1},${cell.col + 1}`, 
                                    cell.x + cell.width / 2, 
                                    cell.y + cell.height / 2);
                    }
                });
            }
            
            // 检查鼠标是否在某个单元格上
            function checkHover(x, y) {
                // 重置所有单元格的悬停状态
                cells.forEach(cell => {
                    cell.isHovered = false;
                });
                
                // 检查鼠标位置
                hoveredCell = null;
                for (let cell of cells) {
                    if (x >= cell.x && x <= cell.x + cell.width &&
                        y >= cell.y && y <= cell.y + cell.height) {
                        cell.isHovered = true;
                        hoveredCell = cell;
                        document.getElementById('cellInfo').textContent = 
                            `行 ${cell.row + 1}, 列 ${cell.col + 1}`;
                        break;
                    }
                }
                
                // 如果没有悬停在任何单元格上
                if (!hoveredCell) {
                    document.getElementById('cellInfo').textContent = '未选择';
                }
                
                // 重绘网格
                drawGrid();
            }
            
            // 处理单元格点击
            function handleClick(x, y) {
                // 查找被点击的单元格
                for (let cell of cells) {
                    if (x >= cell.x && x <= cell.x + cell.width &&
                        y >= cell.y && y <= cell.y + cell.height) {
                        // 切换选中状态
                        cell.isSelected = !cell.isSelected;
                        selectedCell = cell.isSelected ? cell : null;
                        break;
                    }
                }
                
                // 重绘网格
                drawGrid();
            }
            
            // 调整Canvas大小以适应窗口
            function resizeCanvas() {
                const containerWidth = canvas.parentElement.clientWidth;
                const containerHeight = 500; // 默认高度
                
                // 设置Canvas尺寸
                canvas.width = containerWidth;
                canvas.height = containerHeight;
                
                // 重新初始化网格
                initGrid(containerWidth, containerHeight);
                
                // 重绘网格
                drawGrid();
            }
            
            // 事件监听
            canvas.addEventListener('mousemove', (e) => {
                const rect = canvas.getBoundingClientRect();
                const x = e.clientX - rect.left;
                const y = e.clientY - rect.top;
                checkHover(x, y);
            });
            
            canvas.addEventListener('click', (e) => {
                const rect = canvas.getBoundingClientRect();
                const x = e.clientX - rect.left;
                const y = e.clientY - rect.top;
                handleClick(x, y);
            });
            
            // 重置按钮
            document.getElementById('resetBtn').addEventListener('click', () => {
                cells.forEach(cell => {
                    cell.isSelected = false;
                });
                selectedCell = null;
                document.getElementById('cellInfo').textContent = '未选择';
                drawGrid();
            });
            
            // 自适应大小按钮
            document.getElementById('resizeBtn').addEventListener('click', resizeCanvas);
            
            // 初始化
            initGrid(canvas.width, canvas.height);
            drawGrid();
        });
    </script>
</body>
</html>